package com.xuelangyun.form.sys.service.impl;

import java.util.HashSet;
import java.util.Set;

import com.xuelangyun.form.common.redis.RedisOperateUtils;
import com.xuelangyun.form.common.utils.TokenGenerator;
import com.xuelangyun.form.sys.service.ISysConfigService;
import com.xuelangyun.form.sys.service.ISysUserTokenService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class SysUserTokenServiceImpl implements ISysUserTokenService {
    //60分钟后过期
    private final static int EXPIRE = 60 * 60 * 1000;

    /**
     * token记录用户ID 前缀
     */
    public final static String TOKEN_PREFIX = "token_user.";

    /**
     * 用户ID记录token 前缀
     */
    public final static String USER_PREFIX = "user_token.";

    @Autowired
    private ISysConfigService configService;


    @Autowired
    private RedisOperateUtils redisUtils;

    /*
     * 获取token过期时间  单位 分钟
     */
    private Integer getExpireTime() {
        String key = "login_expire_time";
        if (redisUtils.containKey(key)) {
            return redisUtils.get(key, Integer.class);
        }

        Integer time = EXPIRE;

        String expireTime = configService.getValue(key);
        if (expireTime != null && expireTime.trim().matches("^\\d+$")) {
            time = Integer.valueOf(expireTime.trim());

        }

        redisUtils.set(key, time);

        return time;
    }

    @Override
    public String createToken(String userId) {

        // 判断是否允许多地登录
        String repeatLogin = configService.getValue("repeat_login");
        String token = null;

        int time = getExpireTime();
        //生成一个token
        token = TokenGenerator.generateValue();

        // 判断是否可以重复登录
        if (repeatLogin == null || StringUtils.isBlank(repeatLogin) || !(repeatLogin.trim().toLowerCase().equals("1") || repeatLogin.trim().toLowerCase().equals("true"))) {
            // 不可以重复登录 这里直接清理历史token
            // 查出来之前的token 作废缓存
            clearUserTokenCache(userId);
        }

        Set<String> tokenAdd = new HashSet<>();
        tokenAdd.add(token);
        // userid 存token
        redisUtils.set(USER_PREFIX + userId, tokenAdd, time);
        // token id存userid
        redisUtils.set(TOKEN_PREFIX + token, userId, time);

        return token;
    }

    public void clearUserTokenCache(String userId) {
        //根据userid找到token
        Set<String> tokens = queryTokenByUserId(userId);
        if (tokens != null && !tokens.isEmpty()) {
            for (String token : tokens) {
                redisUtils.deleteContains(token);
            }
        }
        redisUtils.delete(USER_PREFIX + userId);
    }

    @Override
    public void logout(String userId) {
        clearUserTokenCache(userId);
    }

    /**
     * 基于redis,如果redis没有开启则不管
     */
    @Override
    public Set<String> queryTokenByUserId(String userId) {
        return redisUtils.get(USER_PREFIX + userId, Set.class);
    }

    @Override
    public String queryUserIdByToken(String token) {
        return redisUtils.get(TOKEN_PREFIX + token, String.class);
    }

    public void expireToken(String token) {
        int time = getExpireTime();
        redisUtils.expire(TOKEN_PREFIX + token, time);
        // 获取userId
        String userId = redisUtils.get(TOKEN_PREFIX + token, String.class);
        if (userId != null) {
            redisUtils.expire(USER_PREFIX + userId, time);
        }
    }
}
